﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Windows.Storage;
using BlogApp.Data.Models;
using Microsoft.Phone.Net.NetworkInformation;

namespace BlogApp.Data.Service
{
    public class DataServiceBase
    {
        private static Dictionary<string, long> _cacheDict = new Dictionary<string, long>();
        private static int _maxCacheAge = 3600;


        public event EventHandler<NetworStatusEventArgs> NetworkStatusChanged;

        private bool _isOffline;
        public bool IsOffline
        {
            get { return _isOffline; }
            set
            {
                _isOffline = value;
                NetworkStatusChanged(this, new NetworStatusEventArgs() { IsOffline = value });
            }
        }

        private void NetworkStatusChangeDetected(object sender, NetworkNotificationEventArgs e)
        {
            switch (e.NotificationType)
            {
                case NetworkNotificationType.InterfaceConnected:
                    {
                        IsOffline = false;
                        break;
                    }

                case NetworkNotificationType.InterfaceDisconnected:
                    {
                        IsOffline = true;
                        break;
                    }
            }
        }

        public DataServiceBase()
        {
            DeviceNetworkInformation.NetworkAvailabilityChanged += NetworkStatusChangeDetected;
        }


        //private HttpClient createHttpClient(string requestUrl)
        private HttpClient createHttpClient()
        {
            var handler = new HttpClientHandler();
            return new HttpClient(handler);
        }

        protected void removeFromCache(string key)
        {
            if (_cacheDict.ContainsKey(key))
            {
                _cacheDict.Remove(key);
            }
        }

        /// <summary>
        /// Makes an asynchrouns GET request.
        /// </summary>
        /// <param name="url">URL to send the Request to</param>
        /// <param name="localCacheKey">If localCacheKey is set, the local caching mechanism will be actiabed using the key.
        /// If the key is missing or null (default value), the caching will not be used</param>
        /// <returns>A string with the result of the request</returns>
        protected async Task<String> GetAsync(string url)
        {
            string js = null;
            try
            {
                var result = await GetAsync(createMessage(HttpMethod.Get, url));

                if (result == null)
                    IsOffline = true;
                
                return result;
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error sending Get Request: " + ex.Message);
            }

            IsOffline = true;
            return null;
        }

        private static HttpRequestMessage createMessage(HttpMethod method, string url)
        {
            Debug.WriteLine(url);
            //m.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");

            var m = new HttpRequestMessage { Method = method, RequestUri = new Uri(url) };
            return m;
        }

        protected async Task<String> GetAsync(HttpRequestMessage msg)
        {
            string js = null;

            try
            {
                //var client = createHttpClient(msg.RequestUri.AbsoluteUri);
                var client = createHttpClient();
                
                var result = await client.SendAsync(msg);
                //var result = await client.GetAsync(url);
                if (result.IsSuccessStatusCode)
                {
                    js = await result.Content.ReadAsStringAsync();
                }
            }
            catch (WebException webEx)
            {
                IsOffline = true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Error sending Get Request: " + ex.Message);
            }

            return !String.IsNullOrEmpty(js) ? js : null;
        }

        public async Task<HttpResponseBinaryData> GetBinaryDataResponseAsync(string url)
        {
            var response = new HttpResponseBinaryData();
            var client = createHttpClient();
            try
            {
                var result = await client.GetAsync(url);
                if (result != null)
                {
                    response.HttpResponse = result;
                    if (result.IsSuccessStatusCode)
                    {
                        response.Bytes = await result.Content.ReadAsByteArrayAsync();
                    }
                }
                return response;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }

            return response;
        }


        #region Caching/Offline

        //protected async Task writeToTempCache(string key, string data)
        //{
        //    var fileName = keyToFileName(key);

        //    try
        //    {
        //        var localFolder = ApplicationData.Current.TemporaryFolder;

        //        var file = await localFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
        //        await FileIO.WriteTextAsync(file, data);
        //    }
        //    catch (Exception ex)
        //    {
        //        Debug.WriteLine(string.Format("Error saving {0} to storage:", fileName));
        //        Debug.WriteLine(ex.Message);
        //    }
        //}

        //protected async Task<String> readFromTempCache(string key)
        //{
        //    var fileName = keyToFileName(key);

        //    var localFolder = ApplicationData.Current.TemporaryFolder;

        //    try
        //    {
        //        var file = await localFolder.GetFileAsync(fileName);
        //        if (file != null)
        //        {
        //            var data = await FileIO.ReadTextAsync(file);
        //            return data;
        //        }
        //        else
        //        {
        //            return null;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Debug.WriteLine("Error reading File {0} from Temp Cache:", fileName);
        //        Debug.WriteLine(ex.Message);
        //        return null;
        //    }
        //}

        //protected static async void deleteFile(string key, bool roamingData = false)
        //{
        //    try
        //    {
        //        var fileName = keyToFileName(key);
        //        var localFolder = roamingData ? ApplicationData.Current.RoamingFolder : ApplicationData.Current.LocalFolder;
        //        var file = await localFolder.GetFileAsync(fileName);
        //        await file.DeleteAsync();
        //    }
        //    catch (Exception e)
        //    {
        //        Debug.WriteLine("Error deleting file {0}: {1}", key, e.Message);
        //    }
        //}

        //protected static async void SaveStringtoFile(string key, string data, bool roamingData = false)
        //{
        //    try
        //    {
        //        var fileName = keyToFileName(key);

        //        var localFolder = roamingData ? ApplicationData.Current.RoamingFolder : ApplicationData.Current.LocalFolder;

        //        var file = await localFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
        //        await FileIO.WriteTextAsync(file, data);
        //        // Workaround as the application terminated before the file was written correctly
        //        await Task.Delay(100);
        //    }
        //    catch
        //    {
        //        Debug.WriteLine(string.Format("Error saving {0} to storage", key));
        //    }
        //}

        //protected static async Task<String> LoadStringFromFile(string key, bool roamingData = false)
        //{
        //    var fileName = keyToFileName(key);

        //    var localFolder = roamingData ? ApplicationData.Current.RoamingFolder : ApplicationData.Current.LocalFolder;

        //    try
        //    {
        //        var file = await localFolder.GetFileAsync(fileName);
        //        if (file != null)
        //        {
        //            var data = await FileIO.ReadTextAsync(file);
        //            return data;
        //        }
        //        else
        //        {
        //            return null;
        //        }
        //    }
        //    catch
        //    {
        //        return null;
        //    }
        //}

        //private static string keyToFileName(string key)
        //{
        //    return String.Format("{0}.cache", key);
        //}

        #endregion



    }
}